import Hls from 'hls.js'

/**
 * 获取图片代理 URL 设置
 */
export function getImageProxyUrl(): string | null {
  if (typeof window === 'undefined')
    return null

  // 本地未开启图片代理，则不使用代理
  const enableImageProxy = localStorage.getItem('enableImageProxy')
  if (enableImageProxy !== null) {
    if (!JSON.parse(enableImageProxy) as boolean) {
      return null
    }
  }

  const localImageProxy = localStorage.getItem('imageProxyUrl')
  if (localImageProxy != null) {
    return localImageProxy.trim() ? localImageProxy.trim() : null
  }

  // 如果未设置，则使用全局对象
  const serverImageProxy = (window as any).RUNTIME_CONFIG?.IMAGE_PROXY
  return serverImageProxy && serverImageProxy.trim()
    ? serverImageProxy.trim()
    : null
}

/**
 * 检查是否为外部图片（需要代理的图片）
 */
function isExternalImage(url: string): boolean {
  if (!url)
    return false

  // 跳过相对路径
  if (url.startsWith('/') || url.startsWith('./') || url.startsWith('../'))
    return false

  // 跳过 data URL
  if (url.startsWith('data:'))
    return false

  try {
    const urlObj = new URL(url)
    const currentHost = typeof window !== 'undefined' ? window.location.hostname : 'localhost'

    // 如果是相同域名，不需要代理
    if (urlObj.hostname === currentHost)
      return false

    // 检查是否为已知的需要代理的域名
    const needsProxyDomains = [
      // 豆瓣相关域名
      'doubanio.com',
      'douban.com',
      'img1.doubanio.com',
      'img2.doubanio.com',
      'img3.doubanio.com',
      'img9.doubanio.com',

      // 其他图片域名
      'yczy5.com',
      'mtzy0.com',
      'img.jisuimage.com',
      'yzzy8.com',
      'btzy8.com',
      'ztzy8.com',
      'cjtt.com',
      'kkzy8.com',
      'bttuku.com',
      'img.liangnizi.com',
      'tu.52av.one',
      'p1.so.tn',
      'p2.so.tn',
      'p3.so.tn',
      'ikgambwqeqnv.com',
      'tu.ikgambwqeqnv.com',
      'imgwolong.com',

      // API站点域名（来自config.json）
      'caiji.dyttzyapi.com',
      'json.heimuer.xyz',
      'heimuer.tv',
      'cj.rycjapi.com',
      'bfzyapi.com',
      'tyyszy.com',
      'ffzy5.tv',
      '360zy.com',
      'caiji.maotaizy.cc',
      'wolongzyw.com',
      'jszyapi.com',
      'dbzy.tv',
      'mozhuazy.com',
      'www.mdzyapi.com',
      'api.zuidapi.com',
      'm3u8.apiyhzy.com',
      'api.wujinapi.me',
      'wwzy.tv',
      'ikunzyapi.com',
      'cj.lziapi.com',
      'zy.xmm.hk',
    ]

    return needsProxyDomains.some(domain => urlObj.hostname.includes(domain))
  }
  catch {
    // 如果 URL 解析失败，不使用代理
    return false
  }
}

/**
 * 处理图片 URL，如果设置了图片代理则使用代理
 */
export function processImageUrl(originalUrl: string): string {
  if (!originalUrl)
    return originalUrl

  // 如果是外部图片（非相对路径和非本域名），使用代理
  if (isExternalImage(originalUrl)) {
    return `/api/image-proxy?url=${encodeURIComponent(originalUrl)}`
  }

  const proxyUrl = getImageProxyUrl()
  if (!proxyUrl)
    return originalUrl

  return `${proxyUrl}${encodeURIComponent(originalUrl)}`
}

/**
 * 处理图片 URL 并添加回退机制
 * 用于需要错误处理的组件
 */
export function processImageUrlWithFallback(originalUrl: string, fallbackUrl?: string): string {
  if (!originalUrl)
    return fallbackUrl || ''

  try {
    const processedUrl = processImageUrl(originalUrl)
    // 如果处理后的URL是代理URL，但原始URL不在需要代理的域名列表中，直接返回原始URL
    if (processedUrl.includes('/api/image-proxy') && !isExternalImage(originalUrl)) {
      return originalUrl
    }
    return processedUrl
  }
  catch (error) {
    console.warn('处理图片URL失败，使用回退URL:', error)
    return fallbackUrl || originalUrl
  }
}

/**
 * 获取豆瓣代理 URL 设置
 */
export function getDoubanProxyUrl(): string | null {
  if (typeof window === 'undefined')
    return null

  // 本地未开启豆瓣代理，则不使用代理
  const enableDoubanProxy = localStorage.getItem('enableDoubanProxy')
  if (enableDoubanProxy !== null) {
    if (!JSON.parse(enableDoubanProxy) as boolean) {
      return null
    }
  }

  const localDoubanProxy = localStorage.getItem('doubanProxyUrl')
  if (localDoubanProxy != null) {
    return localDoubanProxy.trim() ? localDoubanProxy.trim() : null
  }

  // 如果未设置，则使用全局对象
  const serverDoubanProxy = (window as any).RUNTIME_CONFIG?.DOUBAN_PROXY
  return serverDoubanProxy && serverDoubanProxy.trim()
    ? serverDoubanProxy.trim()
    : null
}

/**
 * 处理豆瓣 URL，如果设置了豆瓣代理则使用代理
 */
export function processDoubanUrl(originalUrl: string): string {
  if (!originalUrl)
    return originalUrl

  const proxyUrl = getDoubanProxyUrl()
  if (!proxyUrl)
    return originalUrl

  return `${proxyUrl}${encodeURIComponent(originalUrl)}`
}

export function cleanHtmlTags(text: string): string {
  if (!text)
    return ''
  return text
    .replace(/<[^>]+>/g, '\n') // 将 HTML 标签替换为换行
    .replace(/\n+/g, '\n') // 将多个连续换行合并为一个
    .replace(/[ \t]+/g, ' ') // 将多个连续空格和制表符合并为一个空格，但保留换行符
    .replace(/^\n+|\n+$/g, '') // 去掉首尾换行
    .replace(/&nbsp;/g, ' ') // 将 &nbsp; 替换为空格
    .trim() // 去掉首尾空格
}

/**
 * 从m3u8地址获取视频质量等级和网络信息
 * @param m3u8Url m3u8播放列表的URL
 * @returns Promise<{quality: string, loadSpeed: string, pingTime: number}> 视频质量等级和网络信息
 */
export async function getVideoResolutionFromM3u8(m3u8Url: string): Promise<{
  quality: string // 如720p、1080p等
  loadSpeed: string // 自动转换为KB/s或MB/s
  pingTime: number // 网络延迟（毫秒）
}> {
  try {
    // 直接使用m3u8 URL作为视频源，避免CORS问题
    return new Promise((resolve, reject) => {
      const video = document.createElement('video')
      video.muted = true
      video.preload = 'metadata'

      // 测量网络延迟（ping时间） - 使用m3u8 URL而不是ts文件
      const pingStart = performance.now()
      let pingTime = 0

      // 测量ping时间（使用m3u8 URL）
      fetch(m3u8Url, { method: 'HEAD', mode: 'no-cors' })
        .then(() => {
          pingTime = performance.now() - pingStart
        })
        .catch(() => {
          pingTime = performance.now() - pingStart // 记录到失败为止的时间
        })

      // 固定使用hls.js加载
      const hls = new Hls()

      // 设置超时处理
      const timeout = setTimeout(() => {
        hls.destroy()
        video.remove()
        reject(new Error('Timeout loading video metadata'))
      }, 4000)

      video.onerror = () => {
        clearTimeout(timeout)
        hls.destroy()
        video.remove()
        reject(new Error('Failed to load video metadata'))
      }

      let actualLoadSpeed = '未知'
      let hasSpeedCalculated = false
      let hasMetadataLoaded = false

      let fragmentStartTime = 0

      // 检查是否可以返回结果
      const checkAndResolve = () => {
        if (
          hasMetadataLoaded
          && (hasSpeedCalculated || actualLoadSpeed !== '未知')
        ) {
          clearTimeout(timeout)
          const width = video.videoWidth
          if (width && width > 0) {
            hls.destroy()
            video.remove()

            // 根据视频宽度判断视频质量等级，使用经典分辨率的宽度作为分割点
            const quality
              = width >= 3840
                ? '4K' // 4K: 3840x2160
                : width >= 2560
                  ? '2K' // 2K: 2560x1440
                  : width >= 1920
                    ? '1080p' // 1080p: 1920x1080
                    : width >= 1280
                      ? '720p' // 720p: 1280x720
                      : width >= 854
                        ? '480p'
                        : 'SD' // 480p: 854x480

            resolve({
              quality,
              loadSpeed: actualLoadSpeed,
              pingTime: Math.round(pingTime),
            })
          }
          else {
            // webkit 无法获取尺寸，直接返回
            resolve({
              quality: '未知',
              loadSpeed: actualLoadSpeed,
              pingTime: Math.round(pingTime),
            })
          }
        }
      }

      // 监听片段加载开始
      hls.on(Hls.Events.FRAG_LOADING, () => {
        fragmentStartTime = performance.now()
      })

      // 监听片段加载完成，只需首个分片即可计算速度
      hls.on(Hls.Events.FRAG_LOADED, (event, data) => {
        if (
          fragmentStartTime > 0
          && data
          && data.payload
          && !hasSpeedCalculated
        ) {
          const loadTime = performance.now() - fragmentStartTime
          const size = data.payload.byteLength || 0

          if (loadTime > 0 && size > 0) {
            const speedKBps = size / 1024 / (loadTime / 1000)

            // 立即计算速度，无需等待更多分片
            const avgSpeedKBps = speedKBps

            if (avgSpeedKBps >= 1024) {
              actualLoadSpeed = `${(avgSpeedKBps / 1024).toFixed(1)} MB/s`
            }
            else {
              actualLoadSpeed = `${avgSpeedKBps.toFixed(1)} KB/s`
            }
            hasSpeedCalculated = true
            checkAndResolve() // 尝试返回结果
          }
        }
      })

      hls.loadSource(m3u8Url)
      hls.attachMedia(video)

      // 监听hls.js错误
      hls.on(Hls.Events.ERROR, (event, data) => {
        if (data.fatal) {
          clearTimeout(timeout)
          hls.destroy()
          video.remove()
          reject(new Error(`HLS播放失败: ${data.type}`))
        }
      })

      // 监听视频元数据加载完成
      video.onloadedmetadata = () => {
        hasMetadataLoaded = true
        checkAndResolve() // 尝试返回结果
      }
    })
  }
  catch (error) {
    throw new Error(
      `Error getting video resolution: ${error instanceof Error ? error.message : String(error)
      }`,
    )
  }
}
